#include "mpi.h"
#include <stdio.h>

typedef struct {
	char c;
	double d[6];
	char b[7];
} Partstruct;

int main(int argc, char *argv[]) {
	Partstruct particle[1000];
	int i, j, myrank;
	MPI_Status status;
	MPI_Datatype Particletype;
	MPI_Datatype type[3] = { MPI_CHAR, MPI_DOUBLE, MPI_CHAR };
	int blocklen[3] = { 1, 6, 7 };

	MPI_Aint disp[3];
	MPI_Init(&argc, &argv);

	int particle_address, c_address, d_address, b_address;
	MPI_Aint base;
	particle[0].c = 'c';
	std::fill(particle[0].d, particle[0].d + 6, 3.0f);
	std::fill(particle[0].b, particle[0].b + 7, 'a');

	particle[1].c = 'd';
	std::fill(particle[1].d, particle[1].d + 6, 4.0f);
	std::fill(particle[1].b, particle[1].b + 7, 'e');

	MPI_Get_address(&particle[0], &base);
	MPI_Get_address(&particle[0].c, &disp[0]);
	MPI_Get_address(&particle[0].d, &disp[1]);
	MPI_Get_address(&particle[0].b, &disp[2]);

	for (int i = 0; i < 3; i++) {
		disp[i] = disp[i] - base;
	}

	/*disp[0] = &particle[0].c - &particle[0];
	 disp[1] = &particle[0].d - &particle[0];
	 disp[2] = &particle[0].b - &particle[0];*/
	MPI_Type_create_struct(3, blocklen, disp, type, &Particletype);
	MPI_Type_commit(&Particletype);

	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

	if (myrank == 0) {
		MPI_Send(particle, 1000, Particletype, 1, 123, MPI_COMM_WORLD);
	} else if (myrank == 1) {
		MPI_Recv(particle, 1000, Particletype, 0, 123, MPI_COMM_WORLD, &status);

		printf("rank=%d c:%c, d:%f, b:%c\n", myrank, particle[0].c,
				particle[0].d[0], particle[0].b[0]);
		printf("rank=%d c:%c, d:%f, b:%c\n", myrank, particle[1].c,
				particle[1].d[0], particle[1].b[0]);

	}
	MPI_Finalize();
	return 0;
}
